//package com.goldman.aplt.base.interceptor;
//
//import com.goldman.aplt.base.annotation.EncryptedColumn;
//import com.goldman.aplt.base.annotation.EncryptedTable;
//import com.goldman.aplt.base.type.BaseEnumType;
//import com.goldman.aplt.util.EncryUtil;
//import org.apache.ibatis.executor.resultset.ResultSetHandler;
//import org.apache.ibatis.plugin.*;
//import org.springframework.core.annotation.AnnotationUtils;
//import org.springframework.stereotype.Component;
//
//import java.lang.reflect.Field;
//import java.sql.Statement;
//import java.util.*;
//
///**
// * 字段解密拦截器
// */
//@Intercepts({
//        @Signature(type = ResultSetHandler.class, method = "handleResultSets", args = {Statement.class})
//})
//@Component
//public class DbDecryptInterceptor implements Interceptor {
//
//    @Override
//    public Object intercept(Invocation invocation) throws Throwable {
//        Object resultObject = invocation.proceed();
//        if (Objects.isNull(resultObject)) {
//            return null;
//        }
//        if (resultObject instanceof ArrayList) {
//            //基于selectList
//            ArrayList resultList = (ArrayList) resultObject;
//            if (!resultList.isEmpty() && needToDecrypt(resultList.get(0))) {
//                for (Object result : resultList) {
//                    //逐一解密
//                    decrypt(result);
//                }
//            }
//        } else if (needToDecrypt(resultObject)) {
//            //基于selectOne
//            decrypt(resultObject);
//        }
//        return resultObject;
//    }
//
//    /**
//     * 校验该实例的类是否被@EncryptedTable所注解
//     */
//    private boolean needToDecrypt(Object object) {
//        Class<?> objectClass = object.getClass();
//        EncryptedTable sensitiveData = AnnotationUtils.findAnnotation(objectClass, EncryptedTable.class);
//        return Objects.nonNull(sensitiveData);
//    }
//
//    @Override
//    public Object plugin(Object o) {
//        return Plugin.wrap(o, this);
//    }
//
//    private <T> T decrypt(T result) throws Exception {
//        //取出resultType的类
//        Class<?> resultClass = result.getClass();
//        Field[] declaredFields = resultClass.getDeclaredFields();
//
//        Map<BaseEnumType.E_ENCRY_TYPE, Set<String>> decryRequestMap = new HashMap<>();
//        Map<String, Field> fieldMap = new HashMap<>();
//
//        for (Field field : declaredFields) {
//            //取出所有被EncryptedColumn注解的字段
//            EncryptedColumn sensitiveField = field.getAnnotation(EncryptedColumn.class);
//            if (!Objects.isNull(sensitiveField)) {
//                field.setAccessible(true);
//                Object object = field.get(result);
//                //只支持String的解密
//                if (object instanceof String) {
//                    String value = (String) object;
//
//                    if (decryRequestMap.containsKey(sensitiveField.encryType())) {
//                        Set<String> list = decryRequestMap.get(sensitiveField.encryType());
//                        list.add(value);
//                    } else {
//                        Set<String> list = new HashSet<String>();
//                        list.add(value);
//                        decryRequestMap.put(sensitiveField.encryType(), list);
//                    }
//                    fieldMap.put(value, field);
//                }
//            }
//        }
//
//        Set<Map.Entry<BaseEnumType.E_ENCRY_TYPE, Set<String>>> entries = decryRequestMap.entrySet();
//        Iterator<Map.Entry<BaseEnumType.E_ENCRY_TYPE, Set<String>>> it = entries.iterator();
//        while (it.hasNext()) {
//            Map.Entry<BaseEnumType.E_ENCRY_TYPE, Set<String>> entry = it.next();
//            Set<String> keys = entry.getValue();
//
//            Map<String, String> decryResultMap = EncryUtil.decry(keys.stream().toArray(String[]::new), entry.getKey());
//
//            decryResultMap.forEach((k, v) -> {
//                Field field = fieldMap.get(k);
//                try {
//                    field.set(result, v);
//                } catch (IllegalAccessException e) {
//                    throw new RuntimeException(e);
//                }
//            });
//        }
//
//        return result;
//    }
//
//}
